package net.uman.framework.modules.objectpool;

import java.util.Date;
import java.util.List;
import java.util.Map;

import net.uman.entity.IdEntity;
import net.uman.framework.modules.orm.Page;
import net.uman.framework.modules.orm.PropertyFilter;
import net.uman.framework.modules.orm.PropertyFilter.MatchType;

import org.hibernate.criterion.Criterion;

public class KeyGenerator {
	public static String getKey(String hql, Object... values) {
		StringBuffer sb = new StringBuffer();
		sb.append(hql);
		if (values != null && values.length > 0) {
			for (Object v : values) {
				if (v instanceof Date) {
					sb.append(":"+((Date)v).getTime());
				} else {
					sb.append(":"+v.toString());
				}
			}		
		}
		return sb.toString();
	}

	public static String getKey(Page page, String hql, Object... values) {
		StringBuffer sb = new StringBuffer();
		sb.append("P"+page.getPageSize()).append("."+page.getPageNo()).append(":").append(hql);
		if (values != null && values.length > 0) {
			for (Object v : values) {
				if (v instanceof Date) {
					sb.append(":"+((Date)v).getTime());
				} else {
					sb.append(":"+v.toString());
				}
			}		
		}
		return sb.toString();
	}

	public static String getKey(final String hql, Map<String, ?> values) {
		StringBuffer sb = new StringBuffer();
		sb.append(hql);
		if (values != null && values.size() > 0) {
			for (String key : values.keySet()) {
				sb.append(":").append(key);
				Object v = values.get(key);
				if (v instanceof Date) {
					sb.append("="+((Date)v).getTime());
				} else {
					sb.append("="+v.toString());
				}
			}
		}
		return sb.toString();
	}
	
	public static String getKey(Page page, final String hql, Map<String, ?> values) {
		StringBuffer sb = new StringBuffer();
		sb.append("P"+page.getPageSize()).append("."+page.getPageNo()).append(":").append(hql);
		if (values != null && values.size() > 0) {
			for (String key : values.keySet()) {
				sb.append(":").append(key);
				Object v = values.get(key);
				if (v instanceof Date) {
					sb.append("="+((Date)v).getTime());
				} else {
					sb.append("="+v.toString());
				}
			}
		}
		return sb.toString();
	}

	public static String getKey(Class entityClass, Page page, PropertyFilter.RelationType rel, final Criterion... criterions) {
		StringBuffer sb = new StringBuffer();
		sb.append(getEntityClassName(entityClass)).append(":");
		sb.append("P"+page.getPageSize()).append("."+page.getPageNo()).append(":");
		sb.append(rel).append(":");
		if (criterions != null) {
			for (Criterion criterion : criterions) {
				sb.append(":").append(criterion);
			}
		}
		return sb.toString();
	}

	public static String getKey(Class entityClass, String propertyName, Object value) {
		return getKey(entityClass, propertyName, value, MatchType.EQ);
	}
	
	public static String getKey(Class entityClass, String propertyName, Object value, final MatchType matchType) {
		StringBuffer sb = new StringBuffer();
		sb.append(getEntityClassName(entityClass)).append(":");
		sb.append(propertyName).append(":");
		if (value instanceof Date) {
			sb.append(""+((Date)value).getTime());
		} else {
			sb.append(value.toString());
		}
		sb.append(":").append(matchType.toString());
		return sb.toString();
	}
	
	public static String getKey(Class entityClass, List<PropertyFilter> filters) {
		StringBuffer sb = new StringBuffer();
		sb.append(getEntityClassName(entityClass)).append(":");
		if (filters != null && filters.size() > 0) {
			for (PropertyFilter filter : filters) {
				sb.append(filter.getPropertyName()).append(":");
				Object value = filter.getPropertyValue();
				if (value instanceof Date) {
					sb.append(""+((Date)value).getTime());
				} else {
					sb.append(value.toString());
				}
				sb.append(":").append(filter.getMatchType().toString());
			}
		}
		return sb.toString();		
	}

	public static String getKey(Class entityClass, Page page, List<PropertyFilter> filters) {
		StringBuffer sb = new StringBuffer();
		sb.append(getEntityClassName(entityClass)).append(":");
		sb.append("P"+page.getPageSize()).append("."+page.getPageNo()).append(":");
		if (filters != null && filters.size() > 0) {
			for (PropertyFilter filter : filters) {
				sb.append(filter.getPropertyName());
				sb.append(":").append(filter.getMatchType().toString()).append(":");
				Object value = filter.getPropertyValue();
				if (value instanceof Date) {
					sb.append(""+((Date)value).getTime());
				} else {
					sb.append(value.toString());
				}
			}
		}
		return sb.toString();		
	}

	
	public static String getKey(IdEntity obj) {
		return getKey(obj.getClass(), obj.getId());
	}
	public static String getKey(Class entityClass, Long id) {
		StringBuffer sb = new StringBuffer();
		sb.append(getEntityClassName(entityClass)).append("@"+id);
		return sb.toString();
	}
	
	private static String getEntityClassName(Class entityClass) {
		String clsName = entityClass.getName();
		if (clsName.contains("$$")) {
			clsName = entityClass.getSuperclass().getName();
		}
		return clsName;
	}
}
